﻿using System;
#if TASKSUPPORT
using System.Threading.Tasks;
#endif
using JetBrains.Annotations;
#if NETFX_CORE
using Windows.UI.Core;
#else
using System.Windows.Threading;
#endif


namespace MugenMvvmToolkit.Interfaces
{
    /// <summary>
    ///     Represents the interface for work with threads.
    /// </summary>
    public interface IThreadManager
    {
#if !NETFX_CORE
        /// <summary>
        ///     Gets or sets a dispatcher associated with current UI thread.
        /// </summary>
        Dispatcher UiDispatcher { get; }

#if WPF
        /// <summary>
        /// Gets or sets the priority of asynchronous operations.
        /// </summary>
        DispatcherPriority AsynchronousPriority { get; }

        /// <summary>
        /// Gets or sets the priority of synchronous operations.
        /// </summary>
        DispatcherPriority SynchronousPriority { get; }

        /// <summary>
        ///     Invokes an action on the UI thread using the UiDispatcher.
        /// </summary>
        /// <param name="action">
        ///     The specified <see cref="Action" />.
        /// </param>
        /// <param name="priority">The specified <see cref="DispatcherPriority"/> to invoke the action.</param>
        void InvokeInUi([NotNull]Action action, DispatcherPriority priority);

        /// <summary>
        ///     Invokes an action on the UI thread synchronous using the UiDispatcher.
        /// </summary>
        /// <param name="action">
        ///     The specified <see cref="Action" />.
        /// </param>
        /// <param name="priority">The specified <see cref="DispatcherPriority"/> to invoke the action.</param>
        void InvokeInUiSynchronous([NotNull]Action action, DispatcherPriority priority);
#endif

#else
        /// <summary>
        ///     Gets or sets a dispatcher associated with current UI thread.
        /// </summary>
        CoreDispatcher UiDispatcher { get; }

        /// <summary>
        /// Gets or sets the priority of asynchronous operations.
        /// </summary>
        CoreDispatcherPriority AsynchronousPriority { get; }

        /// <summary>
        /// Gets or sets the priority of synchronous operations.
        /// </summary>
        CoreDispatcherPriority SynchronousPriority { get; }

        /// <summary>
        ///     Invokes an action on the UI thread using the UiDispatcher.
        /// </summary>
        /// <param name="action">
        ///     The specified <see cref="Action" />.
        /// </param>
        /// <param name="priority">The specified <see cref="CoreDispatcherPriority"/> to invoke the action.</param>
        void InvokeInUi([NotNull]Action action, CoreDispatcherPriority priority);

        /// <summary>
        ///     Invokes an action on the UI thread synchronous using the UiDispatcher.
        /// </summary>
        /// <param name="action">
        ///     The specified <see cref="Action" />.
        /// </param>
        /// <param name="priority">The specified <see cref="CoreDispatcherPriority"/> to invoke the action.</param>
        void InvokeInUiSynchronous([NotNull]Action action, CoreDispatcherPriority priority);
#endif

        /// <summary>
        /// Determines whether the calling thread is the UI thread.
        /// </summary>        
        /// <returns><c>true</c> if the calling thread is the UI thread; otherwise, <c>false</c>.</returns>
        bool IsUiThread { get; }

        /// <summary>
        ///     Invokes an action on the UI thread using the UiDispatcher.
        /// </summary>
        /// <param name="action">
        ///     The specified <see cref="Action" />.
        /// </param>
        void InvokeInUi([NotNull]Action action);

        /// <summary>
        ///     Invokes an action on the UI thread synchronous using the UiDispatcher.
        /// </summary>
        /// <param name="action">
        ///     The specified <see cref="Action" />.
        /// </param>
        void InvokeInUiSynchronous([NotNull]Action action);

        /// <summary>
        ///     Invokes an action asynchronous.
        /// </summary>
        /// <param name="action">
        ///     The specified <see cref="Action" />.
        /// </param>
        /// <param name="state">The specified state.</param>
        void InvokeAsync([NotNull]Action<object> action, object state = null);

#if TASKSUPPORT
        /// <summary>
        /// Gets or sets a <see cref="TaskScheduler"/> associated with current UI thread.
        /// </summary>
        TaskScheduler UiTaskScheduler { get; }

        /// <summary>
        /// Gets or sets a <see cref="TaskScheduler"/> not associated with current UI thread.
        /// </summary>
        TaskScheduler NonUiTaskScheduler { get; }
#endif
    }
}